package fr.coding.kata.nantes.roman.christophe;


public enum EnumRoman {


    I("I", 1, null),
    IV("IV", 4, I),
    V("V", 5, IV),
    IX("IX", 9, V),
    X("X", 10, IX),
    XL("XL", 40, X),
    L("L", 50, XL),
    XC("XC", 90, L),
    C("C", 100, XC),
    CD("CD", 400, C),
    D("D", 500, CD),
    CM("CM", 900, D),
    M("M", 1000, CM);

    private String theRoman;
    private int theNumeric;
    private EnumRoman theNextMinus;

    EnumRoman(String roman, int numeric, EnumRoman nextMinus) {
        this.theRoman = roman;
        this.theNumeric = numeric;
        this.theNextMinus = nextMinus;
    }

    public static String toRoman(int value) {
        StringBuilder romanBuilder = new StringBuilder();
        int rest = value;
        while (rest > 0) {
            EnumRoman currentRoman = M.isLower(rest);
            romanBuilder.append(currentRoman.theRoman);
            rest = rest - currentRoman.theNumeric;
        }
        return romanBuilder.toString();
    }

    public EnumRoman isLower(int value) {
        int nbValue = value / theNumeric;
        if (nbValue >= 1) {
            return this;
        } else {
            return theNextMinus.isLower(value);
        }
    }

    public static int toNumeral(String roman) {
        String romanRest = roman;
        int numeralValue = 0;
        while (!romanRest.isEmpty()) {
            EnumRoman currentEnum = M.startWith(romanRest);
            numeralValue = numeralValue + currentEnum.theNumeric;
            romanRest = romanRest.substring(currentEnum.theRoman.length());
        }
        return numeralValue;
    }

    private EnumRoman startWith(String roman) {
        if (roman.startsWith(theRoman)) {
            return this;
        } else {
            return theNextMinus.startWith(roman);
        }
    }
}
